package user

import (
	"context"
	"fmt"
	"private-domain-overseas-service/app/business/api/internal/repository/integral"
	"private-domain-overseas-service/app/business/api/internal/repository/system"
	"private-domain-overseas-service/app/business/api/internal/repository/user"
	"private-domain-overseas-service/app/business/api/internal/svc"
	"private-domain-overseas-service/app/business/api/internal/types"
	"private-domain-overseas-service/pkg/common"
	"private-domain-overseas-service/pkg/constant"
	"private-domain-overseas-service/pkg/status/bizsystemsmsrecord"
	"private-domain-overseas-service/pkg/status/bizuser"
	"private-domain-overseas-service/pkg/xerr"
	"private-domain-overseas-service/tools/ent"
	"private-domain-overseas-service/tools/ent/hzsystemsmsrecord"
	"private-domain-overseas-service/tools/ent/hzuser"
	"private-domain-overseas-service/tools/ent/predicate"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

type UserCaptchaLoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewUserCaptchaLoginLogic - 验证码登录
func NewUserCaptchaLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserCaptchaLoginLogic {
	return &UserCaptchaLoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserCaptchaLoginLogic) UserCaptchaLogin(req *types.UserCaptchaLoginRequest, ipaddress string) (resp *types.UserCaptchaLoginResponse, err error) {
	// 创建实例
	userDao := user.NewUsersDao(l.ctx, l.svcCtx)
	integralWalletDao := integral.NewIntegralWalletDao(l.ctx, l.svcCtx)
	captchaDao := system.NewSystemSmsRecordDao(l.ctx, l.svcCtx)

	// 获取万能验证码
	universalCaptcha, err := common.GetSystemConfig(constant.HzAdminSystemConfigKey, constant.HzSystemSmsUniversal, l.svcCtx.BizRedis, l.svcCtx.Orm)
	if err != nil {
		l.Errorf("get universal captcha config error, %v", err)
	}

	// 验证短信验证码
	if req.Captcha != universalCaptcha {
		// 获取验证码
		systemSmsConditions := make([]predicate.HzSystemSmsRecord, 0)
		systemSmsConditions = append(systemSmsConditions, hzsystemsmsrecord.SystemSmsPhoneEQ(req.Phone))
		systemSmsConditions = append(systemSmsConditions, hzsystemsmsrecord.SystemSmsExpireAtGTE(time.Now().Unix()))
		captchaInfo, err := captchaDao.SystemSmsRecordConditionsFirst(systemSmsConditions)
		if err != nil {
			return nil, xerr.ErrCodeMsg(xerr.ServerApiCaptchaError, fmt.Sprintf("%s", "校验验证码失败"))
		}

		// 校验验证码
		if captchaInfo.SystemSmsCaptcha != req.Captcha {
			return nil, xerr.ErrCodeMsg(xerr.ServerApiCaptchaError, fmt.Sprintf("%s", "校验验证码失败"))
		}

		// 协程处理修改验证码信息
		go func() {
			defer func() {
				if r := recover(); r != nil {
					logx.Errorf("修改验证码信息失败 goroutine panic: %v", r)
				}
			}()
			err = l.handlerSystemSmsRecordUpdate(captchaInfo)
			if err != nil {
				logx.Errorf("修改验证码信息失败：%v", err)
			}
		}()
	}

	// 查询用户信息
	userConditions := make([]predicate.HzUser, 0)
	userConditions = append(userConditions, hzuser.UserPhoneEQ(req.Phone))
	userInfo, _ := userDao.GetOneUser(userConditions)
	if userInfo == nil {
		err = common.WithTx(l.ctx, l.svcCtx.Orm, func(tx *ent.Tx) error {
			// 添加用户
			userInfo, err = userDao.CreateUser(req.Phone, ipaddress, tx)
			if err != nil {
				return xerr.ErrCodeMsg(xerr.ServerOperationExceptionError, fmt.Sprintf("添加用户失败:%v", err))
			}

			// 初始化用户积分钱包
			_, err := integralWalletDao.CreateWallet(int32(userInfo.ID), tx)
			if err != nil {
				return xerr.ErrCodeMsg(xerr.ServerOperationExceptionError, fmt.Sprintf("初始化用户积分钱包失败:%v", err))
			}
			return nil
		})
	}

	//生成token
	accessSecret := l.svcCtx.Config.Auth.AccessSecret
	accessExpire := l.svcCtx.Config.Auth.AccessExpire
	token, err := common.JwtCreate(accessSecret, accessExpire, fmt.Sprint(userInfo.ID))
	if err != nil {
		return nil, xerr.ErrCodeMsg(xerr.ServerCommonError, "生成token失败")
	}

	// 处理用户登录日志
	go func() {
		defer func() {
			if r := recover(); r != nil {
				logx.Errorf("记录用户:%d,登录日志失败：%v", userInfo.ID, err)
			}
		}()
		userLoginLogsCreate := &ent.HzUserLoginLogs{
			UserID:      int64(userInfo.ID),
			LoginType:   bizuser.LoginType,
			DeviceType:  req.DeviceType,
			EquipmentID: req.EquipmentId,
			IPAddress:   ipaddress,
		}
		err = l.handlerCreateUserLoginLogs(userLoginLogsCreate)
		if err != nil {
			logx.Errorf("记录用户:%d,登录日志失败：%v", userInfo.ID, err.Error())
		}
	}()

	//返回token
	resp = &types.UserCaptchaLoginResponse{Token: token}
	return resp, nil
}

// 处理验证码修改状态
func (l *UserCaptchaLoginLogic) handlerSystemSmsRecordUpdate(captchaInfo *ent.HzSystemSmsRecord) error {
	// 创建实例
	captchaDao := system.NewSystemSmsRecordDao(context.Background(), l.svcCtx)

	// 修改验证码使用状态
	var captchaUpdate = ent.HzSystemSmsRecord{
		ID:                   captchaInfo.ID,
		SystemSmsArea:        captchaInfo.SystemSmsArea,
		SystemSmsCaptcha:     captchaInfo.SystemSmsCaptcha,
		SystemSmsPhone:       captchaInfo.SystemSmsPhone,
		SystemSmsMessage:     captchaInfo.SystemSmsMessage,
		SystemSmsDescription: captchaInfo.SystemSmsDescription,
		SystemSmsType:        captchaInfo.SystemSmsType,
		SystemSmsPlatform:    captchaInfo.SystemSmsPlatform,
		SystemSmsStatus:      bizsystemsmsrecord.SmsStatusUse,
		SystemSmsSendAt:      captchaInfo.SystemSmsSendAt,
		SystemSmsExpireAt:    captchaInfo.SystemSmsExpireAt,
		UpdateAt:             time.Now().Unix(),
	}
	if err := captchaDao.SystemSmsRecordUpdate(&captchaUpdate, nil); err != nil {
		return err
	}

	return nil
}

// handlerCreateUserLoginLogs - 处理用户登录日志
func (l *UserCaptchaLoginLogic) handlerCreateUserLoginLogs(userLoginLogs *ent.HzUserLoginLogs) error {
	userLoginLogsDao := user.NewUserLoginLogsDao(context.Background(), l.svcCtx)

	// 记录登录日志
	err := userLoginLogsDao.CreateUserLoginLog(userLoginLogs, nil)
	if err != nil {
		return err
	}

	return nil
}
